﻿#include "FindHistoryDockWidget.h"
#include"FindFundNameThread.h"
#include"TableWindow.h"
#include"MainWindow.h"
#include"FundInfoDockWidget.h"
#include"FuncEvent.h"
#include"FindFundDialog.h"
#include"Thread.h"
#include"ReturnEventFilter.h"
#include"ResizeWindowEventFilter.h"
#include<QPushButton>
#include<QButtonGroup>
#include<QComboBox>
#include<QFileDialog>
#include<QMessageBox>
#include<QLabel>
#include<QDialog>
#include<QLineEdit>
#include<QIntValidator>
#include<QCompleter>
#include<QDebug>
FindHistoryDockWidget::FindHistoryDockWidget(FindFund* Fund, MainWindow* parent)
    :QDockWidget("基金历史信息", parent),
    m_FindFund(Fund)
{
    installEventFilter(new FuncEventFilter(this));
    connect(this, &FindHistoryDockWidget::sendMessage, parent, &MainWindow::showMessage);
    
    QSize buttSize(200, 50); int y = 20;
    {
        m_Label = new QLabel("当前数据空", this);
        m_Label->move(0, y);
        m_Label->resize(buttSize);
        m_Label->setAlignment(Qt::AlignCenter);
    }
    
    {
        m_ComboBox = new QComboBox(this);
        y += buttSize.height();
        m_ComboBox->move(0, y);
        m_ComboBox->resize(buttSize);
        InitComboBox();
    }
    
    m_ButtonGroup = new QButtonGroup(this);
    auto ButtonFindAll = new QPushButton("联网获取所有基金的信息", this);
    m_ButtonGroup->addButton(ButtonFindAll);
    connect(ButtonFindAll, &QPushButton::clicked,this, &FindHistoryDockWidget::FindAll);
    
    auto ButtonFindOne = new QPushButton("联网获取指定基金代码的信息", this);
    m_ButtonGroup->addButton(ButtonFindOne);
    connect(ButtonFindOne, &QPushButton::clicked, this, &FindHistoryDockWidget::FindOne);

    auto ButtonFindAllSave = new QPushButton("联网获取所有基金的信息并导出", this);
    m_ButtonGroup->addButton(ButtonFindAllSave);
    connect(ButtonFindAllSave, &QPushButton::clicked, this, &FindHistoryDockWidget::FindAllSave);

    auto ButtonRead = new QPushButton("读取本地文件", this);
    m_ButtonGroup->addButton(ButtonRead);
    connect(ButtonRead, &QPushButton::clicked, this, &FindHistoryDockWidget::ReadFile);

    auto ButtonAllRead = new QPushButton("读取本地目录", this);
    m_ButtonGroup->addButton(ButtonAllRead);
    connect(ButtonAllRead, &QPushButton::clicked, this, &FindHistoryDockWidget::ReadFileAll);

    auto ButtonSave = new QPushButton("导出当前数据到本地目录", this);
    m_ButtonGroup->addButton(ButtonSave);
    connect(ButtonSave, &QPushButton::clicked, this, &FindHistoryDockWidget::SaveFile);

    auto ButtonSaveAll = new QPushButton("导出全部数据到本地目录", this);
    m_ButtonGroup->addButton(ButtonSaveAll);
    connect(ButtonSaveAll, &QPushButton::clicked, this, &FindHistoryDockWidget::SaveFileAll);

    m_ButtonHidden = new QPushButton("显示数据", this);
    m_ButtonGroup->addButton(m_ButtonHidden);
    connect(m_ButtonHidden, &QPushButton::clicked,this,&FindHistoryDockWidget::TableHidden);
    m_ButtonHidden->setEnabled(false);

    //按钮大小设置排序
    for (auto button : m_ButtonGroup->buttons())
    {
        y += buttSize.height();
        button->move(0, y);
        button->resize(buttSize);
    }
    installEventFilter(new ResizeWindowEventFilter([=](QResizeEvent* ev)->bool {
        for (auto button : m_ButtonGroup->buttons())
        {
            button->setFixedWidth(width());
            m_Label->setFixedWidth(width());
            m_ComboBox->setFixedWidth(width());
        }
        return true;
        }, this));
}

void FindHistoryDockWidget::setButtonEnabled(const bool flag)
{
    auto child = m_ButtonGroup->buttons();
    for (auto& v : child)
    {
        auto button = (QPushButton*)v;
        button->setEnabled(flag);
    }
}

const int FindHistoryDockWidget::FindOneHistory(const int Code)
{
     auto info=m_FindFund->FindName(Code);
     QString code = m_FindFund->FindCode(Code);
    QString str = QString("正在查询%1(%2)的历史数据").arg(info).arg(code);
    sendMessage(str,5000);
    //qInfo() << str;
    auto find = new FindFundNameThread(this);
    find->FindHistoryOne(m_FindFund, Code, 1000);
    //返回结果
    connect(find, &FindFundNameThread::ret, [=](int n) {
        QString str = QString("查询到%1(%2)%3条历史数据").arg(info).arg(code).arg(n);
    sendMessage(str,5000);
    if (n == 0)
        return;
    auto func = [=]()->bool {
        //设置下拉框组合框
        if(m_ComboBox->findText(code) <0)
        {
            /*qInfo() << "插入";*/
            m_ComboBox->addItem(code);
        }
        QString str = QString("%1(%2)\r\n%3条历史数据").arg(info).arg(code).arg(n);
        m_Label->setText(str);

        //设置下拉框组合框
        m_ComboBox->setCurrentIndex(m_ComboBox->findText(code));
        m_ButtonHidden->setEnabled(true);
        return true;
    };
     new FuncEvent(this,func);//发送事件
        });
    find->start();
    return 0;
}

void FindHistoryDockWidget::FindAll()
{
    auto findAll = [=] ()->bool{
        int sum = m_FindFund->FundForm().size();
        int i = 1; 
        auto find = new FindFundNameThread(this);
        find->FindAllHistoryAll(m_FindFund, 1000);
        connect(find, &FindFundNameThread::FindCode, [=](int val) mutable {
            QString name = m_FindFund->FundForm()[val].name;
            QString str = QString("正在查询%1(%2)的历史信息     %3-%4").arg(name).arg(m_FindFund->FindCode(val)).arg(i).arg(sum);
        sendMessage(str);
        ++i;
            });
        connect(find, &FindFundNameThread::ret, [=](int val) {
            QString strCode = m_FindFund->FindCode(val);
            //QString info = m_FindFund->FundForm()[val].name;
            //int n = m_FindFund->FundHistory()[val].size();
            if (m_ComboBox->findText(strCode) < 0)
            {
                m_ComboBox->addItem(strCode);
            }
       /* QString str = QString("%1(%2)\r\n%3条历史数据").arg(info).arg(val).arg(n);
        m_Label->setText(str);*/
            });
        connect(find, &FindFundNameThread::finished, [=] {
            new FuncEvent(this, [=]()->bool {
                setButtonEnabled(true);
                return true;
                });
            });
        setButtonEnabled(false);
        find->start();
        return true;
    };
    {
        setButtonEnabled(false);
        sendMessage("开始获取基金明细",5000);
        auto findFundForm= new FindFundNameThread(this);
        findFundForm->FindFundName(m_FindFund);
        connect(findFundForm, &FindFundNameThread::ret, [=](int val) {
            QString str = QString("查询到%1条基金明细").arg(val);
            sendMessage(str,5000);
            new FuncEvent(this, findAll);
            });
        findFundForm->start();
    }
}

void FindHistoryDockWidget::FindAllSave()
{

    QString FileName = QFileDialog::getExistingDirectory(this, tr("保存"), "Fund");
    if (FileName.isEmpty())
        return;
    
    auto findAll = [=] ()->bool{
        //qInfo() << "开始查询";
        int sum = m_FindFund->FundForm().size();
        static auto i = new int;
        (*i) = 0;
        auto find = new FindFundNameThread(this);
        find->FindAllHistoryWriteAll(m_FindFund, FileName, 1000);
        connect(find, &FindFundNameThread::FindCode, [=](int val) {
         /*   QString name = m_FindFund->FundForm()[val].name;
        QString str = QString("正在查询%1(%2)的历史信息     %3-%4").arg(name).arg(m_FindFund->FindCode(val)).arg(*i).arg(sum);
        sendMessage(str);*/
       
            });
        connect(find, &FindFundNameThread::retCodeAndCount, [=](int code, int count) {
            QString strCode = m_FindFund->FindCode(code);
        QString info = m_FindFund->FundForm()[code].name;
        if (m_ComboBox->findText(strCode) < 0)
        {
            m_ComboBox->addItem(strCode);
        }
        ++(*i);
         QString str = QString("查询到%1(%2)\r\n%3条历史数据     %4-%5").arg(info).arg(strCode).arg(count).arg(*i).arg(sum);
         sendMessage(str, 5000);
            });
        connect(find, &FindFundNameThread::retCodeAndCountAndFileName, [=](int code, int count, QString FileName) {
            QString strCode = m_FindFund->FindCode(code);
        QString info = m_FindFund->FundForm()[code].name;
        QString str = QString("%1(%2)\r\n%3条写入%6     %4-%5").arg(info).arg(strCode).arg(count).arg(*i).arg(sum).arg(FileName);
        sendMessage(str, 5000);
            });
        connect(find, &FindFundNameThread::finished, [=] {
            new FuncEvent(this, [=]()->bool {
                setButtonEnabled(true);
                return true;
                });
            });
        setButtonEnabled(false);
        find->start();
        return true;
    };
    setButtonEnabled(false);
    sendMessage("开始获取基金明细", 5000);
    auto findFundForm = new FindFundNameThread(this);
    findFundForm->FindFundName(m_FindFund);
    connect(findFundForm, &FindFundNameThread::ret, [=](int val) {
        QString str = QString("查询到%1条基金明细").arg(val);
    sendMessage(str, 5000);
    new FuncEvent(this, findAll);
        });
    findFundForm->start();
}

void FindHistoryDockWidget::ReadFile()
{
    QString FileName = QFileDialog::getOpenFileName(this, tr("保存"), "Fund", tr("(*.csv)"));
    if (FileName.isEmpty())
        return;
    sendMessage("文件读取中，请稍后",1000);
    //m_FindFund->claerFundForm();
    int n = m_FindFund->ReadHistoryOne(FileName);
    if (n == 0)
    {
        QMessageBox::critical(this, "警告", "本次文件读取失败\r\n请确认文件是本软件导出的");
        sendMessage("文件读取失败\r\n");
        m_Label->setText("0条记录");
        m_ButtonHidden->setEnabled(false);
        return;
    }
    QString str = QString("读取了%1条记录\r\n文件路径:%2").arg(n).arg(FileName);
    QMessageBox::information(this, "完成", str);
    QFileInfo path(FileName);
    QString Code = path.baseName();
    if (m_ComboBox->findText(Code) == -1)
    {
        m_ComboBox->addItem(Code);
    }
    m_ComboBox->setCurrentText(Code);
}

void FindHistoryDockWidget::ReadFileAll()
{
    QString FilePath = QFileDialog::getExistingDirectory(this, tr("打开"), "Fund");
    if (FilePath.isEmpty())
        return;
    QDir dir(FilePath);
    QStringList filters;
    filters << "*.csv" ;
    dir.setNameFilters(filters);
    auto list=dir.entryInfoList();
    int i = 0;
    for (auto& File : list)
    {
        auto name = File.baseName().toInt();
        if(name==0)
            list.remove(i);
        i++;
    }
    auto read = new FindFundNameThread(this);
    read->ReadHistoryAll(m_FindFund,list);
    static int* currentNum = new int(1);
    static int* maxNum = new int(0);
    (*maxNum) = list.count();
    connect(read, &FindFundNameThread::retCodeAndCountAndFileName, [=](int code, int count, QString FileName) {
        auto name = m_FindFund->FindName(code);
        auto Code = m_FindFund->FindCode(code);
    QString str = QString("%1(%2)读取%6条  %3    %4-%5").arg(name).arg(Code).arg(FileName).arg(*currentNum).arg((*maxNum)).arg(count);
    sendMessage(str, 5000);
    (*currentNum)++;
    if (count == 0)
        return;
    if (m_ComboBox->findText(Code) == -1)
    {
        m_ComboBox->addItem(Code);
    }
    //m_ComboBox->setCurrentText(Code);
    
        });
    connect(read, &FindFundNameThread::finished, [=]() {(*currentNum) = 1; });
    read->start();
}

void FindHistoryDockWidget::SaveFile()
{
    if (m_ComboBox->currentIndex()==-1)
    {
        QMessageBox::critical(this, "警告", "内存中并没有数据\r\n请先联网获取数据或导入文件");
        return;
    }
    //QString path = QString("Fund/%1.csv").arg(m_ComboBox->currentText());
    QString FileName = QFileDialog::getExistingDirectory(this, tr("保存"), "Fund");
    if (FileName.isEmpty())
        return;

    int n = m_FindFund->WriteHistoryOne(m_ComboBox->currentText().toInt(), FileName);
    QString str = QString("保存了%1条记录\r\n文件路径:%2/%3.csv").arg(n).arg(FileName).arg(m_ComboBox->currentText());
    QMessageBox::information(this, "完成", str);
}

void FindHistoryDockWidget::SaveFileAll()
{
   /* qInfo() << sizeof(long long);*/
    if (m_ComboBox->currentIndex() == -1)
    {
        QMessageBox::critical(this, "警告", "内存中并没有数据\r\n请先联网获取数据或导入文件");
        return;
    }
    QString FileName = QFileDialog::getExistingDirectory(this, tr("保存"), "Fund");
    if (FileName.isEmpty())
        return;
    auto find = new FindFundNameThread(this);
    //获取当前的基金代码列表
    QList<int> code;
    for (size_t i = 0; i < m_ComboBox->count(); i++)
    {
        code << m_ComboBox->itemText(i).toInt();
    }
    find->WriteHistoryAll(m_FindFund, code, FileName);
    static int* currentNum = new int(1);
    connect(find, &FindFundNameThread::FindCode, [=](int code) {//开始发送的信号
        /*QString str=QString("")*/
        
        });
    connect(find, &FindFundNameThread::retCodeAndCount, [=](int code, int count) {//结束发送的信号
    auto name = m_FindFund->FundForm()[code].name;
    auto Code= m_FindFund->FundForm()[code].code;
    QString str = QString("%1(%2)写入%6条  %3/%2.csv    %4-%5").arg(name).arg(Code).arg(FileName).arg(*currentNum).arg(m_ComboBox->count()).arg(count);
    sendMessage(str, 5000);
    (*currentNum)++;
        });
    connect(find, &FindFundNameThread::finished, [=]() {(*currentNum) = 1; });
    find->start();
}

void FindHistoryDockWidget::TableHidden()
{
    int code = m_ComboBox->currentText().toInt();
    int n = m_FindFund->FundHistory()[code].size();
    showTable(code);
    auto info = m_FindFund->FundForm()[code].name;
    if (info.isEmpty())
        info = m_FindFund->FindName(code);
    auto str = QString("%1(%2)\r\n%3条历史数据").arg(info).arg(m_FindFund->FindCode(code)).arg(n);
    m_Label->setText(str);
   /* str = QString("查询到%1(%2)%3条历史数据").arg(info).arg(code).arg(n);
    sendMessage(str);*/
}

void FindHistoryDockWidget::showTable(const int code)
{
    auto Table = ((MainWindow*)parent())->tableWindow();
    Table->clearAll();
    QStringList table_h_headers;
    table_h_headers  << "净值日期" << "单位净值" << "累计净值" << "日增长率" << "申购状态"<< "赎回状态";
    Table->setHorizontalHeading(table_h_headers);
    for (auto& data : m_FindFund->FundHistory()[code])
    {
        auto& Historical = data.second;
        QStringList list;
        list << data.first << QString::number(Historical.AverVal, 'f', 4) << QString::number(Historical.CumuVal, 'f', 4) << QString::number(Historical.probab, 'f', 2)+"%" << Historical.applyPurchase << Historical.redeem;
        //qInfo() << list;
        Table->insertData(list);
    }
    Table->setColumnWidth();
    Table->setTextAlignmentAll(Qt::AlignCenter);
    Table->initRun();
}

void FindHistoryDockWidget::InitComboBox()
{
    m_ComboBox->setEditable(true);
    m_ComboBox->setValidator(new QIntValidator(1, 999999, this));
    m_ComboBox->setInsertPolicy(QComboBox::NoInsert);
    m_ComboBox->setFont(QFont(QString("微软雅黑"), 20));
    m_ComboBox->installEventFilter(new ReturnEventFilter([=] (QKeyEvent* ev)->bool{
        QString code = m_ComboBox->currentText();
    int nSel = m_ComboBox->findText(code);
    if (nSel != -1)
        m_ComboBox->setCurrentIndex(nSel);
    else
    {
        auto info = m_FindFund->FindName(code.toInt());
        if (info.isEmpty())
            QMessageBox::information(this, "温馨提示", "没有这个基金");
        else
            FindOneHistory(code.toInt());
    }
    return true;
        }, m_ComboBox));
    connect(m_ComboBox, &QComboBox::currentIndexChanged, this, &FindHistoryDockWidget::TableHidden);
}

void FindHistoryDockWidget::FindOne()
{
    if (m_FindFundDialog == nullptr)
    {
        m_FindFundDialog = new FindFundDialog(m_FindFund, "请输入基金代码", this);
        connect(m_FindFundDialog, &FindFundDialog::sendMessage, (MainWindow*)parent(), &MainWindow::showMessage);
        m_FindFundDialog->init();
    }
    int codeNum = m_FindFundDialog->exec();
   if(codeNum>0)
    {
        FindOneHistory(codeNum);     
    }
}
